package com.example.movie.ui.cinema

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Build
import android.os.Bundle
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.movie.R
import com.example.movie.common.constants.RequestCode
import com.example.movie.data.cinema.factory.SeatTableViewModelFactory
import com.example.movie.data.cinema.model.vm.SeatTableViewModel
import com.example.movie.data.cinema.model.vo.HallSeatVo
import com.example.movie.data.user.factory.UserViewModelFactory
import com.example.movie.data.user.login.model.SharedLoginViewModel
import com.example.movie.data.user.model.OrderViewModel
import com.example.movie.ui.MainActivity
import com.example.movie.ui.cinema.adapter.SelectedTicketAdapter
import com.example.movie.ui.cinema.view.SeatTable
import com.example.movie.ui.user.auth.LoginActivity
import com.example.movie.ui.user.order.OrderActivity
import com.example.movie.utils.ContextHolder
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton
import kotlinx.android.synthetic.main.fragment_movie_seat.*

class SeatTableActivity : AppCompatActivity() {

    private val seatTableViewModel: SeatTableViewModel by viewModels(factoryProducer = { SeatTableViewModelFactory() })
    private val orderViewModel: OrderViewModel by viewModels(factoryProducer = { UserViewModelFactory() })
    private val loginViewModel: SharedLoginViewModel =
        ContextHolder.from(MainActivity::class).loginViewModel

    private val isValidSeat = hashMapOf<String, Boolean>()
    private val isSold = hashMapOf<String, Boolean>()
    private val idsMap = hashMapOf<String, Int>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.fragment_movie_seat)
        intent?.extras?.getInt("planId")?.let {
            seatTableViewModel.loadSeatData(it)
        }

        seatTableViewModel.seatData.observe(this, {
            with(it.success) {
                this?.let {
                    generateSeatStates(hallSeatVos, movieHallVo.row, movieHallVo.col)
                    refreshTicketState(planVo.seatPrice)

                    selected_tickets.layoutManager =
                        LinearLayoutManager(
                            this@SeatTableActivity,
                            LinearLayoutManager.HORIZONTAL,
                            false
                        )
                    val selectedTicketAdapter = SelectedTicketAdapter(seatTable, payBtn)
                    selected_tickets.adapter = selectedTicketAdapter

                    seatTable.apply {
                        this.setScreenName(planVo.hallName)
                        this.setMaxSelected(5)
                        this.setData(movieHallVo.row, movieHallVo.col)

                        this.setSeatChecker(object : SeatTable.SeatChecker {

                            @RequiresApi(Build.VERSION_CODES.N)
                            override fun isValidSeat(row: Int, column: Int): Boolean {
                                return isValidSeat.getOrDefault(
                                    "$row$column",
                                    isSold.getOrDefault("$row$column", false)
                                )
                            }

                            @RequiresApi(Build.VERSION_CODES.N)
                            override fun isSold(row: Int, column: Int): Boolean {
                                return isSold.getOrDefault("$row$column", false)
                            }

                            override fun checked(row: Int, column: Int) {
                                selectedTicketAdapter.addItem(
                                    selectedTicketAdapter.itemCount,
                                    "" + row + "排" + column + "列",
                                )
                                addTotalPrice(payBtn)
                            }

                            override fun unCheck(row: Int, column: Int) {
                                val element = "" + row + "排" + column + "列"
                                selectedTicketAdapter.removeItem(selectedTicketAdapter.itemsMap[element]!!)
                                deductTotalPrice(payBtn)
                            }

                            override fun checkedSeatTxt(
                                row: Int,
                                column: Int
                            ): Array<String>? {
                                return null
                            }

                        })

                    }

                }
            }
        })

        //购票
        payBtn.setOnClickListener {
            QMUIDialog
                .MessageDialogBuilder(this)
                .setTitle("温馨提示")
                .setMessage("确认购票吗?")
                .addAction("取消") { _dialog: QMUIDialog, _: Int ->
                    _dialog.dismiss()
                }
                .addAction("支付") { _dialog: QMUIDialog, _: Int ->
                    _dialog.dismiss()

                    val ids = getSelectSeatIds()
                    if (loginViewModel.isLoggedIn()) {
                        intent?.extras?.getInt("planId")?.let {
                            orderViewModel.addOrder(
                                ids.joinToString(separator = ","),
                                it
                            )
                        }
                    } else {
                        startActivityForResult(
                            Intent(this, LoginActivity::class.java),
                            RequestCode.NEED_LOGIN
                        )
                    }

                }
                .show()
        }

        orderViewModel.addOrderSate.observe(this, {
            with(it.success) {
                this?.let {
                    startActivity(Intent(this@SeatTableActivity, OrderActivity::class.java))
                }
            }

        })

    }


    private fun getSelectSeatIds(): MutableList<Int> {
        val ids = mutableListOf<Int>()
        val selectedSeats = seatTable.selectedSeat
        repeat(selectedSeats.size) {
            val position = selectedSeats[it].split(",")
            idsMap["${position[0]}${position[1]}"]?.let { it -> ids.add(it) }
        }
        return ids
    }

    /**
     * 生成座位状态矩阵
     */
    private fun generateSeatStates(hallSeatVos: List<HallSeatVo>, row: Int, col: Int) {
        var idx = 0
        for (i in 0 until row) {
            for (j in 0 until col) {
                val hallSeatVo = hallSeatVos[idx++]
                if (hallSeatVo.state == 1) {
                    idsMap["$i$j"] = hallSeatVo.hallSeatId
                    isValidSeat["$i$j"] = true
                } else if (hallSeatVo.state == 3) {
                    isSold["$i$j"] = true
                }
            }

        }
    }

    private fun refreshTicketState(seatPrice: Double) {
        ticketPrice = (seatPrice * radix).toInt()
        totalPrice = 0
    }

    companion object TicketInfo {
        private var totalPrice: Int = 0
        private var ticketPrice: Int = 0
        const val radix: Int = 10000

        @SuppressLint("SetTextI18n")
        fun addTotalPrice(
            payBtn: QMUIRoundButton
        ) {
            val plusPrice = totalPrice.plus(ticketPrice)
            totalPrice = plusPrice
            payBtn.text = "${plusPrice * 1.0 / radix} 确认购票"
            checkEmptySelected(payBtn)
        }

        @SuppressLint("SetTextI18n")
        fun deductTotalPrice(
            payBtn: QMUIRoundButton
        ) {
            val minusPrice = totalPrice.minus(ticketPrice)
            totalPrice = minusPrice
            payBtn.text = "${minusPrice * 1.0 / radix} 确认购票"
            checkEmptySelected(payBtn)
        }

        private fun checkEmptySelected(payBtn: QMUIRoundButton) {
            if (totalPrice == 0) {
                payBtn.text = "请先选座"
            }
        }

    }

}